use std::{collections::BTreeMap, path::PathBuf, thread::JoinHandle};

use clap::{Args, ValueEnum};
use serde::{Deserialize, Serialize};
use wtask_base::{logs::DateTime, error::WResult};

use crate::{file::utils::PathNode, task::utils::args::WTaskSubmitMeta};



pub(crate) static WTASK_SOURCE_FILE: &str = "wTask.source.zip";
pub(crate) static WTASK_DISABLED_FILE: &str = "wTask.disabled.txt";
pub static WTASK_INSTALL_FILES: [&str; 4] = ["README.md", "wTask.Meta.json", "wTask.Run.sh", "wTask.Install.sh"];
pub(crate) static WTASK_README: &str = include_str!("task.md");
pub(crate) static TASK_RUN_META_FILE: &str = "wtask.meta.run.json";
pub(crate) static TASK_RUN_LOG_PREFIX: &str = "wtask.";
pub(crate) static TASK_RUN_LOG_END: &str = ".run.log";




#[derive(Debug, Clone, Serialize, Deserialize)]
pub(super) struct WTaskMetaFile {
    pub(super) name: String,
    pub(super) tags: Vec<String>,
    pub(super) args: WTaskSubmitMeta,
}


#[derive(Debug, Clone, Serialize, Deserialize, ValueEnum, PartialEq, Eq)]
pub enum TaskStatus {
    Waiting,
    Running,
    Success,
    Failed,
    Unknown,
}


#[derive(Debug, Serialize, Deserialize)]
pub struct TaskMeta {
    pub id: String,
    pub name: String,
    pub version: String,
    pub(crate) doc: String,
    pub(crate) cmd: String,
    pub(crate) files: PathNode,
    pub(crate) args: WTaskSubmitMeta,
    pub(crate) tags: Vec<String>,
    pub(crate) enable: bool,
    pub(crate) dir: String,
}


#[derive(Debug, Serialize, Deserialize)]
pub struct TaskList {
    pub apps: Vec<TaskMeta>,
    /// 展示meta，默认展示任务列表
    pub meta: bool,
}


#[derive(Debug, Clone, Serialize, Deserialize, Args)]
pub struct TaskAddMeta {
    /// 任务文件路径，支持文件夹/Git/压缩的任务文件
    pub path: String,

    /// 不等待任务安装脚本运行完成，可以通过任务是否启用看是否安装完成
    #[arg(long)]
    pub no_wait: bool,

    /// 指定版本，格式为时间，%Y_%m_%d_%H_%M_%S，否则为当前时间
    #[arg(long)]
    pub version: Option<String>,
}


#[derive(Debug, Clone, Serialize, Deserialize, Args)]
pub struct TaskSubmitMeta {
    /// 任务备注
    pub note: String,

    /// 运行的任务ID
    pub app: String,

    /// 运行任务的版本，默认最新版
    #[arg(long, default_value = "latest")]
    pub version: String,

    // 指定结果文件夹
    #[arg(long)]
    pub dir_result: Option<String>,

    /// 任务运行标签
    #[arg(long, default_value = "预定义任务")]
    pub tag: String,
    
    /// 任务参数，一般参数有一个值，以name=value形式提供，如果为多个值，则使用@@@间隔，如name=value1@@@value2
    pub args: Vec<String>,
}


#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CmdMeta {
    pub id: String,
    pub(crate) tag: String,
    pub(crate) image: String,
    pub(crate) image_save: Option<String>,
    pub(crate) note: String,
    pub(crate) cmd: Vec<String>,
    pub(crate) exe: String,
    pub(crate) status: TaskStatus,
    pub(crate) time_create: DateTime,
    pub(crate) time_done: Option<DateTime>,
    pub(crate) dir_result: PathBuf,
    pub(crate) envs: BTreeMap<String, String>,
}



#[derive(Debug, Serialize, Deserialize)]
pub struct CmdList {
    pub status: Option<TaskStatus>,
    pub metas: Vec<CmdMeta>,
}












#[derive(Debug, Clone, Serialize, Deserialize, Args)]
pub struct CmdArgs {
    /// 备注此次运行
    pub note: String,

    /// 指定结果文件夹
    #[arg(long)]
    pub dir_result: Option<String>,

    /// 运行任务时的podman镜像，local则为不使用podman运行，unix下运行命令为本地shell，如果启用podman需要设置WTASK_FORCE_PODMAN=1环境变量
    #[arg(long, default_value = "local")]
    pub image: String,

    /// 任务运行标签
    #[arg(long, default_value = "Shell任务")]
    pub tag: String,

    /// 运行的shell命令时用到的环境变量，格式为key=value
    #[arg(long)]
    pub envs: Vec<String>,

    /// 运行的shell命令
    #[arg(required = true, trailing_var_arg = true)]
    pub cmd: Vec<String>,
}


#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CmdRet {
    pub id: String,
    pub exe: String,
    pub dir_result: PathBuf,
}


pub(crate) struct CmdRunningRet {
    pub(crate) basic: CmdRet,
    pub(crate) handle: JoinHandle<WResult<CmdMeta>>,
}

